package org.dataSource;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class DataBaseInfo {

	List<Record> records;

	public DataBaseInfo() {

		DataBase db = new DataBase();
		records = db.readAllRecords();

	}

	public List<Record> getRecords() {
		return records;
	}

	public void setRecords(List<Record> records) {
		this.records = records;
	}
	
	public void setOnlyRecords(String subject){
		
		List<Record> onlyRecords = new ArrayList<Record>();
		
		for (Record record : records) {
			if((subject.equals("Male") && record.getSex().equals("Male"))
			|| (subject.equals("Female") && record.getSex().equals("Female"))
			|| (subject.equals("United-States") && record.getNativeCountry().equals("United-States"))
			|| (subject.equals("Mexican") && record.getNativeCountry().equals("Mexican")))			

				onlyRecords.add(record);
		}
		
		records = onlyRecords;
	}
	
	public int getMaxAge() {

		int maxAge = 0;

		for (Record record : records) {
			if (record.age > maxAge)
				maxAge = record.age;
		}
		return maxAge;
	}

	public int getMinAge() {

		int minAge = 100;

		for (Record record : records) {
			if (record.age < minAge)
				minAge = record.age;
		}
		return minAge;
	}

	public List<Double> getAllAges() {

		List<Double> allAges = new ArrayList<Double>();

		for (Record record : records) {

			allAges.add((double) record.age);

		}

		return allAges;

	}
	
	public int getMaxCapitalGain() {

		int maxGain = 0;

		for (Record record : records) {
			if (record.capitalGain > maxGain)
				maxGain = record.capitalGain;
		}
		return maxGain;
	}

	public int getMinCapitalGain() {

		int minGain = 1000000000;

		for (Record record : records) {
			if (record.capitalGain < minGain)
				minGain = record.capitalGain;
		}
		return minGain;
	}

	public List<Double> getAllCapitalGains() {

		List<Double> allGains = new ArrayList<Double>();

		for (Record record : records) {

			allGains.add((double) record.capitalGain);

		}

		return allGains;

	}
	
	public int getMaxWorkingHours() {

		int maxWorkingHours = 0;

		for (Record record : records) {
			if (record.hoursPerWeek > maxWorkingHours)
				maxWorkingHours = record.hoursPerWeek;
		}
		return maxWorkingHours;
	}

	public int getMinWokingHours() {

		int minWorkingHours = 100000;

		for (Record record : records) {
			if (record.hoursPerWeek < minWorkingHours)
				minWorkingHours = record.hoursPerWeek;
		}
		return minWorkingHours;
	}

	public List<Double> getAllWorkingHours() {

		List<Double> allWorkingHours = new ArrayList<Double>();

		for (Record record : records) {

			allWorkingHours.add((double) record.hoursPerWeek);

		}

		return allWorkingHours;

	}

	/**
	 * zwraca listę płci
	 * @return
	 */
	public List<String> getGenderList() {
		return Arrays.asList(this.getGenders());
	}
	
	/**
	 * zwraca listę płci
	 * @return
	 */
	public String[] getGenders()
	{
		Set<String> genders = this.getGenderSet();
		return genders.toArray(new String[genders.size()]);
	}
	
	/**
	 * zwraca listę płci
	 * @return
	 */
	public Set<String> getGenderSet()
	{
		Set<String> genders = new HashSet<String>();
		
		for(Record g : this.getRecords())
			genders.add(g.getSex());
		
		return genders;
	}
	
	/**
	 * zwraca listę klas
	 * @return
	 */
	public Set<String> getWorkingClasses()
	{
		Set<String> classes = new HashSet<String>();
		
		for(Record r : this.getRecords())
			classes.add(r.getWorkClass());
		
		return classes;
	}
	
	/**
	 * zwraca listę klas wraz z ilością osób  w każdej z klas
	 * @return
	 */
	public Map<String, Integer> getWorkingClassesWithCount()
	{
		Map<String, Integer> map = new HashMap<>();
		
		for(Record r : this.getRecords())
		{
			if(map.containsKey(r.getWorkClass()))
			{
				Integer count = map.get(r.getWorkClass());
				map.put(r.getWorkClass(), ++count);
			}
			else
				map.put(r.getWorkClass(), 1);
		}
		
		return map;
	}
	
	/**
	 * zwraca set edukacji
	 * @return
	 */
	public Set<String> getEducation()
	{
		Set<String> education = new HashSet<String>();
		
		for(Record r : this.getRecords())
			education.add(r.getEducation());
		
		return education;
	}
	
	/**
	 * zwraca listę edukacji wraz z ilością osób  w każdej z klas
	 * @return
	 */
	public Map<String, Integer> getEducationWithCount()
	{
		Map<String, Integer> map = new HashMap<>();
		
		for(Record r : this.getRecords())
		{
			if(map.containsKey(r.getEducation()))
			{
				Integer count = map.get(r.getEducation());
				map.put(r.getEducation(), ++count);
			}
			else
				map.put(r.getEducation(), 1);
		}
		
		return map;
	}
	
	/**
	 * zwraca zestaw [ilość lat edukacji : ilość osób]
	 * @return
	 */
	public Map<Integer, Integer> getEducationYearsWithCount()
	{
		Map<Integer, Integer> education = new HashMap<Integer, Integer>();
		
		for(Record r : this.getRecords())
		{
			if(education.containsKey(r.getEducationYears()))
			{
				Integer count = education.get(r.getEducationYears());
				education.put(r.getEducationYears(), ++count);
			}
			else
				education.put(r.getEducationYears(), 1);
		}
		
		return education;
	}
	
	public int educationYearsMin()
	{
		Map<Integer, Integer> edy = getEducationYearsWithCount();
		
		int min = Integer.MAX_VALUE;
		
		for(Integer e : edy.keySet())
			if(e < min) min = e;
		
		return min;
	}
	
	public int educationYearsMax()
	{
		Map<Integer, Integer> edy = getEducationYearsWithCount();
		
		int max = Integer.MIN_VALUE;
		
		for(Integer e : edy.keySet())
			if(e > max) max = e;
		
		return max;
	}
	
	public Set<String> getMaritalStatusSet()
	{
		Set<String> set = new HashSet<String>();
		
		for(Record r : this.getRecords())
			set.add(r.getMaritalStatus());
		
		return set;
	}
	
	public Map<String, Integer> getMaritalStatusWithCount()
	{
		Map<String, Integer> status = new HashMap<String, Integer>();
		
		for(Record r : this.getRecords())
		{
			if(status.containsKey(r.getMaritalStatus()))
			{
				Integer count = status.get(r.getMaritalStatus());
				status.put(r.getMaritalStatus(), ++count);
			}
			else
				status.put(r.getMaritalStatus(), 1);
		}
		
		return status;
	}
	
	public Map<String, Integer> getOccupationWithCount()
	{
		Map<String, Integer> status = new HashMap<String, Integer>();
		
		for(Record r : this.getRecords())
		{
			if(status.containsKey(r.getOccupation()))
			{
				Integer count = status.get(r.getOccupation());
				status.put(r.getOccupation(), ++count);
			}
			else
				status.put(r.getOccupation(), 1);
		}
		
		return status;
	}
	
	public Map<String, Integer> getRelationshipWithCount()
	{
		Map<String, Integer> status = new HashMap<String, Integer>();
		
		for(Record r : this.getRecords())
		{
			if(status.containsKey(r.getRelationship()))
			{
				Integer count = status.get(r.getRelationship());
				status.put(r.getRelationship(), ++count);
			}
			else
				status.put(r.getRelationship(), 1);
		}
		
		return status;
	}
	
	public Map<String, Integer> getRaceWithCount()
	{
		Map<String, Integer> status = new HashMap<String, Integer>();
		
		for(Record r : this.getRecords())
		{
			if(status.containsKey(r.getRace()))
			{
				Integer count = status.get(r.getRace());
				status.put(r.getRace(), ++count);
			}
			else
				status.put(r.getRace(), 1);
		}
		
		return status;
	}
	
	
	public Map<Integer, Integer> getHoursPerWeekWithCount()
	{
		Map<Integer, Integer> status = new HashMap<Integer, Integer>();
		
		for(Record r : this.getRecords())
		{
			if(status.containsKey(r.getHoursPerWeek()))
			{
				Integer count = status.get(r.getHoursPerWeek());
				status.put(r.getHoursPerWeek(), ++count);
			}
			else
				status.put(r.getHoursPerWeek(), 1);
		}
		
		return status;
	}
	
	public int hoursPerWeekMin()
	{
		Map<Integer, Integer> edy = getHoursPerWeekWithCount();
		
		int min = Integer.MAX_VALUE;
		
		for(Integer e : edy.keySet())
			if(e < min) min = e;
		
		return min;
	}
	
	public int hoursPerWeekMax()
	{
		Map<Integer, Integer> edy = getHoursPerWeekWithCount();
		
		int max = Integer.MIN_VALUE;
		
		for(Integer e : edy.keySet())
			if(e > max) max = e;
		
		return max;
	}
	
	public Map<String, Integer> getNativeCountryWithCount()
	{
		Map<String, Integer> status = new HashMap<String, Integer>();
		
		for(Record r : this.getRecords())
		{
			if(status.containsKey(r.getNativeCountry()))
			{
				Integer count = status.get(r.getNativeCountry());
				status.put(r.getNativeCountry(), ++count);
			}
			else
				status.put(r.getNativeCountry(), 1);
		}
		
		return status;
	}
	
	public Map<String, Integer> getContinentWithCount()
	{
		Map<String, Integer> status = new HashMap<String, Integer>();
		
		for(Record r : this.getRecords())
		{
			if(status.containsKey(r.getContinent()))
			{
				Integer count = status.get(r.getContinent());
				status.put(r.getContinent(), ++count);
			}
			else
				status.put(r.getContinent(), 1);
		}
		
		return status;
	}
	
	public Map<Boolean, Integer> getStatesOrNotWithCount()
	{
		Map<Boolean, Integer> status = new HashMap<Boolean, Integer>();
		
		for(Record r : this.getRecords())
		{
			if(status.containsKey(r.getUnitedStatesOrNot()))
			{
				Integer count = status.get(r.getUnitedStatesOrNot());
				status.put(r.getUnitedStatesOrNot(), ++count);
			}
			else
				status.put(r.getUnitedStatesOrNot(), 1);
		}
		
		return status;
	}
	
}
